﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EasyCore.Excel
{

    /// <summary>
    /// 列配置项：暂只支持最多两行标题
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ColumnOption<T>
    {
        /// <summary>
        /// Excel字段名称
        /// </summary>
        public string ColumnName { get; set; }

        /// <summary>
        /// 列宽
        /// </summary>
        public int ColumnWidth { get; set; } = 20;

        /// <summary>
        /// 数据库字段名称或属性名称
        /// </summary>
        public string FieldName { get; set; }

        /// <summary>
        /// 列值处理格式化函数
        /// </summary>
        public Func<int, T, object> ColumnValFunc { get; set; }

        /// <summary>
        /// 是否隐藏
        /// </summary>
        public bool IsHide { get; set; } = false;
       
        /// <summary>
        /// 孩子节点
        /// </summary>
        public List<ColumnOption<T>> Children { get; set; }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="columnName"></param>
        public ColumnOption(string columnName)
        {
            ColumnName = columnName;    
        }

        /// <summary>
        /// 构造化函数
        /// </summary>
        /// <param name="columnName"></param>
        /// <param name="columnWidth"></param>
        /// <param name="columnValFunc"></param>
        public ColumnOption(string columnName, string fieldName = null, int columnWidth = 20, Func<int, T, object> columnValFunc = null)
        {
            ColumnName = columnName;
            FieldName = fieldName;
            ColumnWidth = columnWidth;
            ColumnValFunc = columnValFunc;
        }

        /// <summary>
        /// 添加子标题
        /// </summary>
        /// <param name="columnAction"></param>
        public void AddChildColumn(string columnName, string fieldName = null, int columnWidth = 20, Func<int, T, object> columnValFunc = null)
        {
            var option = new ColumnOption<T>(columnName, fieldName,columnWidth, columnValFunc);
            if (Children == null) Children = new List<ColumnOption<T>>();      
            Children.Add(option);
        }

        /// <summary>
        /// 获得列宽度
        /// </summary>
        /// <returns></returns>
        public int GetColumnSpan()
        {   
           return CalcColumnSpan(0,this); //当前开始序号为1
        }

        /// <summary>
        /// 重举法计算列的宽度
        /// </summary>
        /// <param name="startIndex"></param>
        /// <param name="columnOption"></param>
        /// <returns></returns>
        private int CalcColumnSpan(int startIndex, ColumnOption<T> columnOption) {
            if (columnOption.Children == null || !columnOption.Children.Any()) return startIndex + 1;//当无子节点时，当前的列宽度为startIndex+1;
            foreach (var child in columnOption.Children) {
                startIndex = CalcColumnSpan(startIndex, child);
            }
            return startIndex;  
        }

        /// <summary>
        /// 获得标题行的深度
        /// </summary>
        /// <returns></returns>
        public int GetRowSpan() {
            return CalcRowSpan(0,this);  
        }

        /// <summary>
        /// 计算当前列的深度
        /// </summary>
        /// <param name="startIndex"></param>
        /// <param name="columnOption"></param>
        /// <returns></returns>
        private int CalcRowSpan(int startIndex, ColumnOption<T> columnOption)
        {
            startIndex = startIndex + 1;
            if (columnOption.Children == null || !columnOption.Children.Any()) return startIndex;//当无子节点时，当前的深度宽度为startIndex+1;            
            List<int> maxList = new List<int>(); 
            foreach (var child in columnOption.Children)
            {
                int rowSpan = CalcRowSpan(startIndex, child);
                maxList.Add(rowSpan);
            }
            return maxList.Max();
        }
    }
}
